<?php if (!defined('NOVA_RUN')) die('You can\'t access this file directly!');

/*
-------------------------------------------------------
*
*   NovaBoard 2
*   Copyright © 2011 NovaBoard team
*
*--------------------------------------------------------
*
*   Official site: www.novaboard.net
*   Contact e-mail: support@novaboard.net
*
*   GNU General Public License, version 2:
*   http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
---------------------------------------------------------
*/

class User_Model extends Model {

	// Reserved group IDs:
		// 0 - Guest
		// 1 - Administrator
		// 2 - Super Moderator
		// 3 - User
		// 4 - Banned
	// ------------------------

	public function __construct()
	{
		parent::__construct();
	}

	// TODO: infinity redirection by Engine::showError(2);
	public function check_user($action)
	{
		if (session_id())
		{
			// Get DB
			$db = db::instance();

			$stmt = $db->select('userCheck', array
			(
				'fields'	=> array('user_id'),
				'tables'	=> 'sessions',
				'where'		=> array('session_id' => array('=', '?')),
				'limit'		=> 1
			));
			$stmt->execute(array(session_id()));

			// Fields list
			$list = array('session_id', 'user_id', 'last_activity', 'last_action', 'last_ip', 'user_agent');

			if ($stmt->rowCount() > 0)
			{
				$id = $stmt->fetchColumn();

				$user = new User_Object($id);
				
				// check permissions
				if (defined('NOVA_ADMIN') && $user->permissions['admincp_access'] == 0)
				{
					Engine::showError(2);
				}

				// Remove first field
				array_shift($list);

				$stmt = $db->update('userUpdateSession', 'sessions', $list, array('session_id' => array('=', '?')));
				$stmt->execute(array($id, time(), $action, $_SERVER['REMOTE_ADDR'], $_SERVER['HTTP_USER_AGENT'], session_id()));

				return $user;
			}
			else
			{
				$id = $this->cookie_auth();

				// update session
				$stmt = $db->insert('userInsertSession', 'sessions', $list);
				$stmt->execute(array(session_id(), $id, time(), $action, $_SERVER['REMOTE_ADDR'], $_SERVER['HTTP_USER_AGENT']));

				// create current user object
				$user = new User_Object($id);

				// check permissions
				if (defined('NOVA_ADMIN') && $user->permissions['admincp_access'] == 0)
				{
					Engine::showError(2);
				}
				
				return $user;
			}
		}
		else
		{
			throw new Exception($this->lang->get('exception', 'phpsessid'));
			return false;
		}
	}

	private function cookie_auth()
	{
		if (get_cookie('user_login') && get_cookie('password_hash'))
		{
			$stmt = db::instance()->select('userCookieAuth', array
			(
				'fields'	=> 'user_id',
				'tables'	=> 'users',
				'where'		=> array('login' => array('=', '?'), 'password' => array('=', '?'), 'activated' => array('=', 1)),
				'limit'		=> 1
			));
			$stmt->execute(array(get_cookie('user_login'), get_cookie('password_hash')));

			if ($stmt->rowCount() > 0)
			{
				setcookie('user_login', get_cookie('user_login'), time() + 3600*24*30);
				setcookie('password_hash', get_cookie('password_hash'), time() + 3600*24*30);

				return $stmt->fetchColumn();
			}
		}

		return 0;
	}

	public function auth()
	{
			$salt = db::instance()->select('userSalt', array
			(
				'fields'	=> 'password_salt',
				'tables'	=> 'users',
				'where'		=> array('login' => array('=', get_request('login', 'post'))),
				'limit'		=> 1
			), true)->fetchColumn();

			$password = md5(mb_substr($salt, 4, 4, 'UTF-8') . addslashes(get_request('password', 'post', false)) . mb_substr($salt, 0, 4, 'UTF-8'));

			$stmt = db::instance()->select('userAuth', array
			(
				'fields'	=> '*',
				'tables'	=> 'users',
				'where'		=> array('login' => array('=', '?'), 'password' => array('=', '?'), 'activated' => array('=', 1)),
				'limit'		=> 1
			));
			$stmt->execute(array(get_request('login', 'post'), $password));

			if ($stmt->rowCount() > 0)
			{
				if (get_request('remember', 'post') == 1)
				{
					setcookie('user_login', get_request('login', 'post'), time() + 3600*24*30, '/');
					setcookie('password_hash', $password, time() + 3600*24*30, '/');
				}

				$user = $stmt->fetch();

				// Fields list
				$list = array('user_id', 'last_activity', 'last_action', 'last_ip', 'user_agent', 'logout_hash');

				// update sessions
				$hash = make_rand('32');
				$stmt = db::instance()->update('userUpdateSessionAuth', 'sessions', $list, array('session_id' => array('=', '?')));
				$stmt->execute(array($user['user_id'], time(), $action, $_SERVER['REMOTE_ADDR'], $_SERVER['HTTP_USER_AGENT'], $hash, session_id()));

				return true;
			}

		return false;
	}

	public function logout()
	{
		setcookie('user_login', get_request('login', 'post'), time() - 3600, '/');
		setcookie('password_hash', $password, time() - 3600, '/');
		db::instance()->delete('userDeleteCurrentSession', 'sessions', array('session_id' => array('=', session_id())), true);
		session_destroy();
		redirect(make_link());
	}
	
	public function register()
	{
		$group = 3; // default user group
		$salt = make_rand(8);
		$password = md5(mb_substr($salt, 4, 4, 'UTF-8') . addslashes(get_request('password', 'post', false)) . mb_substr($salt, 0, 4, 'UTF-8'));
		$actCode = make_rand(32);
		
		$stmt = db::instance()->insert('registerUser', 'users', array(
			'group_id', 'login', 'password', 'password_salt', 'email', 'activation_code', 'activated', 'reg_date'
		));
		$stmt->execute(array($group, get_request('login', 'post'), $password, $salt, get_request('email', 'post'), $actCode, 0, time()));
		
		// send email
	}
	
	public function removeOldSessions($timeout)
	{
		$limit = time() - ($timeout * 60);
		
		db::instance()->delete('userDeleteSessions', 'sessions', array('last_activity' => array('<', $limit)), true);
	}

	public function getUsersOnline()
	{
		$stmt = db::instance()->select('userOnline', array
		(
			'fields'	=> '*',
			'tables'	=> 'sessions',
			'where'		=> array('user_id' => array('>', 0))
		), true);
		
		return $stmt->fetchAll();
	}

	public function getGuestsOnline()
	{
		return db::instance()->select('userGuestsOnline', array
		(
			'fields'	=> '*',
			'tables'	=> 'sessions',
			'where'		=> array('user_id' => array('=', 0))
		), true)->rowCount();
	}

	public function checkLoginExists($login)
	{
		return db::instance()->select('checkLoginExists', array
		(
			'fields'	=> 'user_id',
			'tables'	=> 'users',
			'where'		=> array('login' => array('=', $login)),
			'limit'		=> 1
		), true)->rowCount();
	}

	public function checkGroupExist($id)
	{
		if (!Cache::check('groups_list'))
		{
			$_groups = array();
			$groups = db::instance()->select('getCategoriesList', array
			(
				'fields' => 'group_id',
				'tables' => 'groups'
			), true)->fetchAll();
			
			foreach ($groups as $group)
			{
				$_groups[] = $group['group_id'];
			}
			
			Cache::save('groups_list', $_groups);
		}

		$groups = Cache::load('groups_list');
		return (array_search($id, $groups) !== false) ? 1 : 0;
	}

	public function getGroups()
	{
		return db::instance()->select('getGroups', array
		(
			'fields'	=> '*',
			'tables'	=> 'groups',
		), true)->fetchAll();
	}

	public function checkEmailExists($email)
	{
		return db::instance()->select('checkEmailExists', array
		(
			'fields'	=> 'user_id',
			'tables'	=> 'users',
			'where'		=> array('email' => array('=', $email)),
			'limit'		=> 1
		), true)->rowCount();
	}

	public function activate($id, $code)
	{
		$count = db::instance()->select('checkUserActivate', array
		(
			'fields'	=> 'user_id',
			'tables'	=> 'users',
			'where'		=> array('user_id' => array('=', $id), 'activation_code' => array('=', $code)),
			'limit'		=> 1
		), true)->rowCount();
		
		if ($count < 1)
		{
			return false;
		}
		else
		{
			$stmt = db::instance()->update('UserActivate', 'users', array('activation_code', 'activated'), array('user_id' => array('=', '?')));
			$stmt->execute(array('', 1, $id));
			return true;
		}
	}
}